package mianshi;

public class JVMtext {
    /*
        jvm内存区域:
    1. 程序计数器
    2. 虚拟机栈
    线程私有; 每个方法被执行时,java虚拟机都会创建一个栈帧,栈帧用来存储局部变量表, 操作数栈, 动态连接, 方法出口等信息;每个方法执行的过程对应的就是一个栈帧从入栈到出站的过程;
    其中, 局部变量表包括基本数据类型和对象的引用;在方法运行时, 局部变量表所需要的空间是确定的,也就是说在方法运行期间, 并不会改变局部变量表的大小;
    如果线程请求的栈深度大于虚拟机所允许的深度,那么将会发生栈溢出异常(StackOverFlowError); 如果内存空间不足,也会出现内存溢出异常(OutOfMemoryError)

    3. 本地方法栈
    线程私有,存储native方法(即本地方法), 和虚拟机栈一样, 也会出现栈溢出异常和内存溢出异常

    4. 堆
    线程共享; 存储几乎所有的对象实例; 会产生内存溢出异常, 可通过参数(-Xmx 和 -Xms)设定最大堆内存和最小堆内存

    5. 方法区
    线程共享; 存储常量, 静态变量, 已被虚拟机加载的类型信息, 编译后的代码缓存等; 会出现内存溢出异常

    6. 运行时常量池
    运行时常量池是方法区的一部分,所以也是线程共享的; java文件在编译时会生成一个常量池表, 里面存储了常量数据, 常量池表就会保存在常量池中; 但是, 常量在程序运行的过程中也是会产生的, 比如String类型的数据, 都是保存在运行时常量池中的;
    因为运行时常量池是方法区的一部分, 自然也是受到方法区内存大小的限制的, 因此也会出现内存溢出异常;

    8. 直接内存

*/

    /*
        堆内存
        1.新生代
        2.老年代
        3.永久代
     */

    /*
        垃圾回收算法
        第一步:判断哪些内存需要回收?

        1.引用计数算法
            缺点:对象之间循环引用时,不会被回收
        2.可达性分析算法

        第二步:怎么回收? 即垃圾收集算法

            1.标记-清除算法
                缺点:导致内存碎片化
            2.标记-复制算法(适用于新生代)
            3.标记-整理算法(适用于老年代)

     */

    /*
        java中的四种引用类型
        1.强引用
            Object obj = new Object()
        2.软引用
        实现方式: 继承SoftReference类来实现,
        生命周期:当系统内存不足时,即将要跑出抛出内存溢出异常时,
        软引用的对象会被回收

        3.弱引用
            实现方式: 继承WeakReference类来实现
            生命周期:当出现垃圾回收时,弱引用的对象会被回收
        4.虚引用
            实现方式:继承PhantomReference类来实现
            不能单独使用，必须和引用队列联合使用。 虚引用的
            主要作用是跟踪对象被垃圾回收的状态
     */

    /*
        分代收集算法(主流)和分区收集算法

        分代收集算法:
            新生代(标记-复制算法)和老年代(标记-整理)
            使用不同的垃圾收集算法
        分区收集算法:
            分区算法则将整个堆空间划分为连续的不同小区间,
            每个小区间独立使用, 独立回收. 这样做的好处是可以控制一次回收
            多少个小区间 , 根据目标停顿时间, 每次合理地回收若干个小区间(而
            不是整个堆), 从而减少一次 GC 所产生的停顿
     */

    /*
        常用的垃圾收集器
        1.Serial垃圾收集器(单线程,复制算法)
        2.ParNew垃圾收集器(Serial+多线程)
        3.Parallel Scavenge收集器(多线程复制算法,高效)
        4.Serial Old垃圾收集器(单线程标记整理算法)
        5.Parallel Old收集器(多线程标记整理算法)
        6.CMS垃圾收集器(多线程标记清除算法)
        7.G1收集器
     */

    /*
        jvm类加载机制

        1.加载
            在内存中生成对应的class对象,作为方法区中该类的各种数据的入口
        2.验证
            确保class文件中的字节码是正确的
        3.准备
            在内存中分配初始化该对象所需要的内存
        4.解析
            虚拟机将常量池中的符号引用替换为直接引用的过程
            符号引用? 直接引用?
        5.初始化
            初始化对象

        双亲委派机制

            当一个类收到了类加载请求，他首先不会尝试自己去加载这个类，而是把这个请求委派给父
        类去完成，每一个层次类加载器都是如此，因此所有的加载请求都应该传送到启动类加载其中，
        只有当父类加载器反馈自己无法完成这个请求的时候（在它的加载路径下没有找到所需加载的
        Class）， 子类加载器才会尝试自己去加载。
        采用双亲委派的一个好处是比如加载位于 rt.jar 包中的类 java.lang.Object，不管是哪个加载
        器加载这个类，最终都是委托给顶层的启动类加载器进行加载，这样就保证了使用不同的类加载
        器最终得到的都是同样一个 Object 对象
     */


}
